# !/usr/bin/env python
# -*- coding: utf-8 -*-
"""
 -------------------------------------------------
    File Name:     viewset.py
    Description:   自定义视图集
 -------------------------------------------------
 """
from rest_framework import status
from rest_framework.exceptions import PermissionDenied
from rest_framework.viewsets import ModelViewSet

from utils.json_response import SuccessResponse, DetailResponse
from utils.permission import CustomPermission


class CustomModelViewSet(ModelViewSet):
    """
    自定义的ModelViewSet:
    统一标准的返回格式;新增,查询,修改可使用不同序列化器

    values_queryset：优化查询性能，选择部分字段。
    ordering_fields：控制可排序的字段。
    create_serializer_class 和 update_serializer_class：为创建和更新操作指定不同的序列化器。
    filter_fields：
        ?name=John&is_active=true
        在查询中允许用户通过 URL 参数进行过滤的字段。'__all__'.过滤字段。默认支持全部model中的字段查询(除json字段外)
    search_fields：
        ?search=xxx---
        控制可搜索的xxx字段。定义哪些字段可以用于 全文搜索。这通常与 Django 的 SearchFilter 配合使用
    extra_filter_class：添加额外的过滤逻辑。
    permission_classes：定义权限类，控制谁可以访问视图集。
    import_field_dict 和 export_field_label：用于数据导入和导出的字段映射。
    """
    values_queryset = None
    ordering_fields = '__all__'
    # 序列化器
    create_serializer_class = None  # 创建序列化器
    update_serializer_class = None  # 更新序列化器
    list_serializer_class = None  # 列表序列化器, 自定义
    retrieve_serializer_class = None  # 详情序列化器，自定义
    destroy_serializer_class = None  # 删除序列化器，自定义

    filter_fields = '__all__'
    search_fields = ()
    # extra_filter_class = [CoreModelFilterBankend, DataLevelPermissionsFilter]
    permission_classes = [CustomPermission]  # 目前默认身份校验

    import_field_dict = {}
    export_field_label = {}

    # 允许的方法
    allowed_methods = '__all__'  # 默认允许所有方法，可以设置为['list']等
    # 禁止的方法
    denied_methods = []

    def get_queryset(self):

        # 通过属性来判断是否是允许的操作
        print(f"执行的方法是：{self.action}")
        if self.action in self.denied_methods:
            raise PermissionDenied("此操作被禁用")
        if self.allowed_methods != '__all__' and self.action not in self.allowed_methods:
            raise PermissionDenied("此操作被禁用")

        if getattr(self, 'values_queryset', None):
            return self.values_queryset
        return super().get_queryset()

    def get_serializer_class(self):
        """根据请求方法动态设置序列化器"""
        action_serializer_name = f"{self.action}_serializer_class"
        action_serializer_class = getattr(self, action_serializer_name, None)
        if action_serializer_class:
            return action_serializer_class
        return super().get_serializer_class()

    # 通过many=True直接改造原有的API，使其可以批量创建
    # def get_serializer(self, *args, **kwargs):
    #     serializer_class = self.get_serializer_class()
    #     kwargs.setdefault('context', self.get_serializer_context())
    #     # 全部以可见字段为准
    #     # can_see = self.get_menu_field(serializer_class)
    #     # 在分页器中使用
    #     # self.request.permission_fields = can_see
    #     # if isinstance(self.request.data, list):
    #     #     with transaction.atomic():
    #     #         return serializer_class(many=True, *args, **kwargs)
    #     # else:
    #     #     return serializer_class(*args, **kwargs)
    #     return serializer_class(*args, **kwargs)

    def create(self, request, *args, **kwargs):
        """POST 新增 201"""
        serializer = self.get_serializer(data=request.data)  # , request=request
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        return DetailResponse(data=serializer.data, msg="新增成功", status=status.HTTP_201_CREATED)

    def destroy(self, request, *args, **kwargs):
        """DELETE 删除 204"""
        instance = self.get_object()
        self.perform_destroy(instance)
        return DetailResponse(data=[], msg="删除成功", status=status.HTTP_204_NO_CONTENT)

    def update(self, request, *args, **kwargs):
        """PUT 修改 200"""
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)  # , request=request
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)

        if getattr(instance, '_prefetched_objects_cache', None):
            # If 'prefetch_related' has been applied to a queryset, we need to
            # forcibly invalidate the prefetch cache on the instance.
            instance._prefetched_objects_cache = {}

        return DetailResponse(data=serializer.data, msg="更新成功")

    def list(self, request, *args, **kwargs):
        """GET 查询列表"""
        queryset = self.filter_queryset(self.get_queryset())

        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)  # , request=request
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(queryset, many=True)  # , request=request
        return SuccessResponse(data=serializer.data, msg="获取成功")

    def retrieve(self, request, *args, **kwargs):
        """GET 获取单个对象"""
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        return DetailResponse(data=serializer.data, msg="获取成功")
